package com.jprocms.module.cms.service.sitetpl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.jpro.framework.common.exception.ServerException;
import com.jpro.framework.common.pojo.CommonResult;
import com.jpro.module.infra.api.config.ConfigApi;
import com.jpro.module.infra.api.config.FileConfigApi;
import com.jpro.module.infra.api.config.dto.FileConfigRespVO;
import com.jpro.module.infra.framework.file.core.client.ftp.FtpFileClientConfig;
import com.jpro.module.infra.framework.file.core.client.local.LocalFileClientConfig;
import com.jprocms.module.cms.constant.CmsSysConstants;
import com.jprocms.module.cms.controller.admin.sitetpl.dto.TplReSourceDto;
import com.jprocms.module.cms.controller.admin.sitetpl.dto.TplSaveDirDto;
import com.jprocms.module.cms.dal.dataobject.site.SiteDO;
import com.jprocms.module.cms.dal.dataobject.tplinclude.TplIncludeDO;
import com.jprocms.module.cms.framework.file.FileWrap;
import com.jprocms.module.cms.framework.file.Zipper;
import com.jprocms.module.cms.framework.file.core.client.FileClient;
import com.jprocms.module.cms.framework.file.core.client.FileClientFactory;
import com.jprocms.module.cms.framework.file.core.client.ftp.FtpFileClient;
import com.jprocms.module.cms.framework.file.core.enums.FileStorageEnum;
import com.jprocms.module.cms.service.tplinclude.TplIncludeService;
import com.jprocms.module.cms.util.CmsContextUtil;
import com.jprocms.module.cms.util.FrontContextUtil;
import com.mzt.logapi.context.LogRecordContext;
import com.mzt.logapi.starter.annotation.LogRecord;
import lombok.SneakyThrows;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

import static com.jpro.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.jprocms.module.cms.constant.CmsSysConstants.SPT;
import static com.jprocms.module.cms.enums.ErrorCodeConstants.*;
import static com.jprocms.module.cms.enums.LogRecordConstants.*;

/**
 * 本地模板Service实现类
 *
 * @author jprocms
 */
@Service
public class TplServiceImpl implements TplService {
    private static Logger log = LoggerFactory.getLogger(TplServiceImpl.class);
    private FileClientFactory fileClientFactory;
    private ConfigApi configApi;
    private FileConfigApi fileConfigApi;

    private TplIncludeService tplIncludeService;

    public TplServiceImpl(FileClientFactory fileClientFactory, ConfigApi configApi, FileConfigApi fileConfigApi, TplIncludeService tplIncludeService) {
        this.fileClientFactory = fileClientFactory;
        this.configApi = configApi;
        this.fileConfigApi = fileConfigApi;
        this.tplIncludeService = tplIncludeService;
    }

    private FileClient fileClient;
    //不好调整FileClientConfig,暂时先存储基础路径，ftp和本地两种
    private String basePath;
    //FT存储的配置ID
    private Integer tplStorerage;
    /**
     * 文件夹和可编辑文件则显示
     */
    private FileFilter filter = file -> file.isDirectory() || FileWrap.editableExt(FilenameUtils.getExtension(file.getName()));

    public FileClient getFileClient() {
        if (fileClient == null) {
            initLocalCache();
        }
        return fileClient;
    }

    public void initLocalCache() {
        // 第一步：查询数据
        CommonResult<String> configGetResult = configApi.getConfigValueByKey(CmsSysConstants.TPL_STORE_TYPE_CONFIG_ID);

        if (configGetResult.isSuccess()) {
            Long tplStorerageConfigId = Long.parseLong(configGetResult.getData());
            CommonResult<FileConfigRespVO> fileConfigResult = fileConfigApi.getFileConfig(tplStorerageConfigId);
            if (fileConfigResult.isSuccess()) {
                FileConfigRespVO config = fileConfigResult.getData();
                tplStorerage = config.getStorage();
                fileClientFactory.createOrUpdateFileClient(config.getId(), config.getStorage(), config.getConfig());
                fileClient = fileClientFactory.getFileClient(config.getId());
                if (FileStorageEnum.LOCAL.getStorage().equals(config.getStorage())) {
                    LocalFileClientConfig localFileClientConfig = (LocalFileClientConfig) config.getConfig();
                    basePath = localFileClientConfig.getBasePath();
                    //AbstractFileClient init 追加了 /
                    basePath = basePath.substring(0, basePath.lastIndexOf(File.separator));
                } else if (FileStorageEnum.FTP.getStorage().equals(config.getStorage())
                        || FileStorageEnum.SFTP.getStorage().equals(config.getStorage())) {
                    FtpFileClientConfig ftpFileClientConfig = (FtpFileClientConfig) config.getConfig();
                    basePath = ftpFileClientConfig.getBasePath();
                    if (StringUtils.isNotBlank(basePath) && basePath.endsWith("/")) {
                        basePath = basePath.substring(0, basePath.lastIndexOf("/"));
                    }
                }
            }
        }
    }


    @Override
    @LogRecord(type = CMS_TPL_TYPE, subType = CMS_TPL_DELETE_SUB_TYPE, bizNo = "{{#siteId}}", success = CMS_TPL_DELETE_SUCCESS)
    public void delete(String[] names) throws Exception {
        Assert.notEmpty(names, "names must not null");
        getFileClient();
        for (String name : names) {
            //fileClient.delete(name);
            if (FileStorageEnum.LOCAL.getStorage().equals(tplStorerage)) {
                File file = new File(basePath + name);
                if (!file.exists()) {
                    throw exception(FILE_NOT_EXISTS);
                }
                if (file.isDirectory()) {
                    FileUtils.deleteDirectory(file);
                } else {
                    FileUtils.deleteQuietly(file);
                }
            } else if (FileStorageEnum.FTP.getStorage().equals(tplStorerage)
                    || FileStorageEnum.SFTP.getStorage().equals(tplStorerage)) {
                FtpResFile ftpTpl = new FtpResFile((FtpFileClient) fileClient, basePath);
                FTPFile ftpFile = ftpTpl.get(name);
                if (ftpFile != null) {
                    ftpTpl = new FtpResFile(ftpFile, FilenameUtils.getFullPathNoEndSeparator(name), (FtpFileClient) fileClient, basePath);
                    ftpTpl.deleteFile(name);
                } else {
                    throw exception(FILE_NOT_EXISTS);
                }
            } else {
                throw exception(TPL_STORAGE_NOT_SUPPORT);
            }
        }
        // 记录操作日志上下文
        LogRecordContext.putVariable("siteId", CmsContextUtil.getCurrSiteId());
        LogRecordContext.putVariable("names", names[0]);
    }

    @Override
    public IResFile get(String name) throws IOException {
        getFileClient();
        if (FileStorageEnum.LOCAL.getStorage().equals(tplStorerage)) {
            File f = new File(basePath + name);
            if (f.exists()) {
                LocalResFile fileTpl = new LocalResFile(f, basePath);
                final TplIncludeDO tplInclude = tplIncludeService.getTplInclude(name, CmsContextUtil.getCurrSiteId());
                fileTpl.setIncludePage(false);
                if (tplInclude != null) {
                    fileTpl.setIncludePage(tplInclude.getIncludePage());
                }
                return fileTpl;
            } else {
                throw exception(TPL_NOT_EXISTS);
            }
        } else if (FileStorageEnum.FTP.getStorage().equals(tplStorerage)
                || FileStorageEnum.SFTP.getStorage().equals(tplStorerage)) {
            FtpResFile ftpTpl = new FtpResFile((FtpFileClient) fileClient, basePath);
            FTPFile ftpFile = ftpTpl.get(name);
            if (ftpFile != null) {
                ftpTpl = new FtpResFile(ftpFile, FilenameUtils.getFullPathNoEndSeparator(name), (FtpFileClient) fileClient, basePath);
                final TplIncludeDO tplInclude = tplIncludeService.getTplInclude(name, CmsContextUtil.getCurrSiteId());
                ftpTpl.setIncludePage(false);
                if (tplInclude != null) {
                    ftpTpl.setIncludePage(tplInclude.getIncludePage());
                }
                return ftpTpl;
            } else {
                throw exception(TPL_NOT_EXISTS);
            }
        } else {
            throw exception(TPL_STORAGE_NOT_SUPPORT);
        }
    }

    @Override
    public List<IResFile> getChild(String path) throws IOException {
        getFileClient();
        if (FileStorageEnum.LOCAL.getStorage().equals(tplStorerage)) {
            File file = new File(basePath + path);
            File[] child = file.listFiles();
            if (child != null) {
                List<IResFile> list = new ArrayList<>(child.length);
                for (File f : child) {
                    LocalResFile fileTpl = new LocalResFile(f, basePath);
                    fileTpl.setId(RandomUtil.getSecureRandom().nextInt(Integer.MAX_VALUE));
                    list.add(fileTpl);
                }
                return list;
            } else {
                return Collections.emptyList();
            }
        } else if (FileStorageEnum.FTP.getStorage().equals(tplStorerage)
                || FileStorageEnum.SFTP.getStorage().equals(tplStorerage)) {
            FtpResFile ftpTpl = new FtpResFile((FtpFileClient) fileClient, basePath);
            ((FtpFileClient) fileClient).getFtp().reconnectIfTimeout();
            FTPFile[] ftpFiles = ftpTpl.list(path);
            List<IResFile> tpls = new ArrayList<>(ftpFiles != null ? ftpFiles.length : 0);
            if (ftpFiles != null) {
                for (FTPFile f : ftpFiles) {
                    FtpResFile ftpResFile = new FtpResFile(f, path, (FtpFileClient) fileClient, basePath);
                    ftpResFile.setId(RandomUtil.getSecureRandom().nextInt(Integer.MAX_VALUE));
                    tpls.add(ftpResFile);
                }
                return tpls;
            } else {
                return Collections.emptyList();
            }
        } else {
            throw exception(TPL_STORAGE_NOT_SUPPORT);
        }
    }

    @Override
    public List<IResFile> listFile(String path, boolean dirAndEditable) throws IOException, ServerException {
        getFileClient();
        if (FileStorageEnum.LOCAL.getStorage().equals(tplStorerage)) {
            File parent = new File(basePath + path);
            if (parent.exists()) {
                File[] files;
                if (dirAndEditable) {
                    files = parent.listFiles(filter);
                } else {
                    files = parent.listFiles();
                }
                Arrays.sort(files, new FileWrap.FileComparator());
                List<IResFile> list = new ArrayList<>(files.length);
                for (File f : files) {
                    list.add(new LocalResFile(f, basePath));
                }
                return list;
            } else {
                return Collections.emptyList();
            }
        } else if (FileStorageEnum.FTP.getStorage().equals(tplStorerage)
                || FileStorageEnum.SFTP.getStorage().equals(tplStorerage)) {
            FtpResFile ftpTpl = new FtpResFile((FtpFileClient) fileClient, basePath);
            FTPFile[] ftpFiles = ftpTpl.list(path);
            List<IResFile> tpls = new ArrayList<>(ftpFiles != null ? ftpFiles.length : 0);
            if (ftpFiles != null) {
                for (FTPFile f : ftpFiles) {
                    tpls.add(new FtpResFile(f, path, (FtpFileClient) fileClient, basePath));
                }
                return tpls;
            } else {
                return Collections.emptyList();
            }
        } else {
            throw exception(TPL_STORAGE_NOT_SUPPORT);
        }
    }

    @SneakyThrows
    @Override
    @LogRecord(type = CMS_TPL_TYPE, subType = CMS_TPL_RENAME_SUB_TYPE, bizNo = "{{#siteId}}", success = CMS_TPL_RENAME_SUCCESS)
    public void rename(String orig, String dist) throws ServerException {
        getFileClient();
        if (FileStorageEnum.LOCAL.getStorage().equals(tplStorerage)) {
            File of = new File(basePath + orig);
            File df = new File(basePath + dist);
            if (df.exists()) {
                throw exception(FILE_EXIST_ERROR);
            }
            try {
                if (of.isDirectory()) {
                    FileUtils.moveDirectory(of, df);
                } else {
                    FileUtils.moveFile(of, df);
                }
            } catch (IOException e) {
                log.error("Move template error: " + orig + " to " + dist, e);
            }
        } else if (FileStorageEnum.FTP.getStorage().equals(tplStorerage)
                || FileStorageEnum.SFTP.getStorage().equals(tplStorerage)) {
            FtpFileClient ftpFileClient = (FtpFileClient) fileClient;
            ftpFileClient.reName(orig, dist);
        } else {
            throw exception(TPL_STORAGE_NOT_SUPPORT);
        }
        // 记录操作日志上下文
        LogRecordContext.putVariable("siteId", CmsContextUtil.getCurrSiteId());
        LogRecordContext.putVariable("orig", orig);
        LogRecordContext.putVariable("dist", dist);
    }

    @Override
    public void saveDir(TplSaveDirDto dto) throws IOException {
        getFileClient();
        if (FileStorageEnum.LOCAL.getStorage().equals(tplStorerage)) {
            File df = new File(basePath + dto.getRoot() + SPT + dto.getDirName());
            if (df.exists()) {
                throw exception(FILE_EXIST_ERROR);
            }
            df.mkdirs();
        } else if (FileStorageEnum.FTP.getStorage().equals(tplStorerage)
                || FileStorageEnum.SFTP.getStorage().equals(tplStorerage)) {
            FtpFileClient ftpFileClient = (FtpFileClient) fileClient;
            ftpFileClient.getFtp().reconnectIfTimeout();
            ftpFileClient.saveDir(dto.getRoot() + SPT + dto.getDirName());
        } else {
            throw exception(TPL_STORAGE_NOT_SUPPORT);
        }
    }

    @Override
    public void saveFile(TplReSourceDto dto) throws ServerException, IOException {
        getFileClient();
        if (FileStorageEnum.LOCAL.getStorage().equals(tplStorerage)) {
            String path = basePath + dto.getRoot() + SPT + dto.getFilename();
            File f = new File(path);
            if (f.exists()) {
                throw exception(FILE_EXIST_ERROR);
            }
            FileUtils.writeStringToFile(f, dto.getSource(), StandardCharsets.UTF_8.name());
        } else if (FileStorageEnum.FTP.getStorage().equals(tplStorerage)
                || FileStorageEnum.SFTP.getStorage().equals(tplStorerage)) {
//            String path = dto.getRoot() + SPT + dto.getFilename();
            String path = dto.getFilename();
            FtpResFile ftpTpl = new FtpResFile((FtpFileClient) fileClient, basePath);
            ftpTpl.storeByFilename(path, new ByteArrayInputStream(dto.getSource().getBytes()));
        } else {
            throw exception(TPL_STORAGE_NOT_SUPPORT);
        }
    }

    @Override
    public void uploadTplResFile(String path, MultipartFile file, Boolean isCover) throws ServerException, IOException {
        getFileClient();
        Assert.notNull(file);
        Assert.notNull(path);
        String fileName = file.getOriginalFilename();
        //isCover为空或者isCover为false保留原文件
        if (isCover == null || !isCover) {
            fileName = generateFileName(path, fileName, 0);
        }
        if (FileStorageEnum.LOCAL.getStorage().equals(tplStorerage)) {
            path = basePath + path;
            File directory = new File(path);
            if (!directory.exists()) {
                directory.mkdirs();
            }

            File f = new File(path, fileName);
            File parentFile = f.getParentFile();
            if (!parentFile.exists() || !parentFile.isDirectory()) {
                parentFile.mkdirs();
            }
            file.transferTo(f);
        } else if (FileStorageEnum.FTP.getStorage().equals(tplStorerage)
                || FileStorageEnum.SFTP.getStorage().equals(tplStorerage)) {
            FtpResFile ftpTpl = new FtpResFile((FtpFileClient) fileClient, basePath);
            ftpTpl.storeByFilename(path + SPT + fileName, file.getInputStream());
        } else {
            throw exception(TPL_STORAGE_NOT_SUPPORT);
        }
    }

    @Override
    @LogRecord(type = CMS_TPL_TYPE, subType = CMS_TPL_UPDATE_SUB_TYPE, bizNo = "{{#siteId}}", success = CMS_TPL_UPDATE_SUCCESS)
    public void update(TplReSourceDto dto) throws Exception {
        getFileClient();
        if (FileStorageEnum.LOCAL.getStorage().equals(tplStorerage)) {
            String filePath = basePath + SPT + dto.getFilename();
            File f = new File(filePath);
            //如果原名称和旧名称不一样，做修改名称操作
            if (!dto.getOriginFileName().equals(dto.getFilename())) {
                //修改文件名称
                String os = basePath + SPT + dto.getOriginFileName();
                File of = new File(os);
                String ds = basePath + SPT + dto.getFilename();
                File df = new File(ds);
                if (df.exists()) {
                    throw exception(FILE_EXIST_ERROR);
                }
                if (of.isDirectory()) {
                    FileUtils.moveDirectory(of, df);
                } else {
                    FileUtils.moveFile(of, df);
                }
            }
            FileUtils.writeStringToFile(f, dto.getSource(), StandardCharsets.UTF_8.name());
        } else if (FileStorageEnum.FTP.getStorage().equals(tplStorerage)
                || FileStorageEnum.SFTP.getStorage().equals(tplStorerage)) {
            String newName = dto.getFilename();
            //删除旧的文件，这样就相当于创建了一个修改了原文件
            if (!newName.equals(dto.getOriginFileName())) {
                String[] names = {dto.getOriginFileName()};
                delete(names);
            }
            //创建新的ftp服务器文件
            saveFile(dto);
        } else {
            throw exception(TPL_STORAGE_NOT_SUPPORT);
        }
        LogRecordContext.putVariable("siteId", CmsContextUtil.getCurrSiteId());
        LogRecordContext.putVariable("filename", dto.getFilename());
    }

    @Override
    public List<Zipper.FileEntry> export(SiteDO site, String solution) {
        getFileClient();
        if (FileStorageEnum.LOCAL.getStorage().equals(tplStorerage)) {
            List<Zipper.FileEntry> fileEntrys = new ArrayList<>();
            File tpl = new File(basePath + site.getTplPath(), solution);
            fileEntrys.add(new Zipper.FileEntry("", "", tpl));
            File res = new File(basePath + site.getResourcePath(), solution);
            if (res.exists()) {
                for (File r : res.listFiles()) {
                    fileEntrys.add(new Zipper.FileEntry(FrontContextUtil.R_EXP, r));
                }
            }
            return fileEntrys;
        } else if (FileStorageEnum.FTP.getStorage().equals(tplStorerage)
                || FileStorageEnum.SFTP.getStorage().equals(tplStorerage)) {
            FtpResFile ftpTpl = new FtpResFile((FtpFileClient) fileClient, basePath);
            String tempLocalPath = FileUtils.getTempDirectoryPath();
            ftpTpl.retrieveFile(solution, site.getTplPath(), tempLocalPath + site.getTplPath());
            ftpTpl.retrieveFile(solution, site.getResourcePath(), tempLocalPath + site.getResourcePath());
            List<Zipper.FileEntry> fileEntrys = new ArrayList<>();
            File tpl = new File(tempLocalPath + site.getTplPath(), solution);
            fileEntrys.add(new Zipper.FileEntry("", "", tpl));
            File res = new File(tempLocalPath + site.getResourcePath(), solution);
            if (res.exists()) {
                for (File r : res.listFiles()) {
                    fileEntrys.add(new Zipper.FileEntry(FrontContextUtil.R_EXP, r));
                }
            }
            return fileEntrys;
        } else {
            throw exception(TPL_STORAGE_NOT_SUPPORT);
        }
    }

    @Override
    public void importZip(SiteDO site, File file, Boolean isCover) throws Exception {
        getFileClient();
        String resRoot = site.getResourcePath();
        String tplRoot = site.getTplPath();
        ZipFile zip = new ZipFile(file, "GBK");
        ZipEntry entry;
        String name;
        String filename;
        File outFile;
        File pfile;
        byte[] buf = new byte[1024];
        int len;
        InputStream is = null;
        OutputStream os = null;
        String solution = null;
        String deleteUrl = null;
        String deleteResUrl = null;
        Enumeration<ZipEntry> en = zip.getEntries();
        while (en.hasMoreElements()) {
            name = en.nextElement().getName();
            if (!name.startsWith(FrontContextUtil.R_EXP)) {
                solution = name.substring(0, name.indexOf(SPT));
                deleteUrl = tplRoot + SPT + solution;
                deleteResUrl = site.getResourcePath() + SPT + solution;
                break;
            }
        }
        String newSolution = solution;
        if (solution == null) {
            if (zip != null) {
                zip.close();
            }
            return;
        } else {
            //isCover 为空或false则表示保存重名的模板
            if (isCover == null || !isCover) {
                File dir = new File(basePath + tplRoot + SPT + solution);
                if (dir.exists() && dir.isDirectory()) {
                    newSolution = generateFileName(tplRoot, solution, 0);
                }
            } else {
                if (deleteUrl != null) {
                    delete(new String[]{deleteUrl});
                    delete(new String[]{deleteResUrl});
                }
            }
        }
        en = zip.getEntries();
        while (en.hasMoreElements()) {
            entry = en.nextElement();
            if (!entry.isDirectory()) {
                name = entry.getName();
                name = name.replace(solution, newSolution);
                log.debug("unzip file：{}", name);
                // 模板还是资源
                if (name.startsWith(FrontContextUtil.R_EXP)) {
                    filename = resRoot + SPT + newSolution + name.substring(FrontContextUtil.R_EXP.length());
                } else {
                    filename = tplRoot + SPT + name;
                }
                log.debug("解压地址：{}", filename);
                outFile = new File(basePath + filename);
                pfile = outFile.getParentFile();
                if (!pfile.exists()) {
                    pfile.mkdirs();
                }
                try {
                    is = zip.getInputStream(entry);
                    os = new FileOutputStream(outFile);
                    while ((len = is.read(buf)) != -1) {
                        os.write(buf, 0, len);
                    }
                    if (FileStorageEnum.FTP.getStorage().equals(tplStorerage)
                            || FileStorageEnum.SFTP.getStorage().equals(tplStorerage)) {
                        FtpResFile ftpTpl = new FtpResFile((FtpFileClient) fileClient, basePath);
                        ftpTpl.storeByFilename(filename, new FileInputStream(outFile));
                    }
                } finally {
                    if (is != null) {
                        is.close();
                        is = null;
                    }
                    if (os != null) {
                        os.close();
                        os = null;
                    }
                }
            }
        }
        zip.close();
    }

    @Override
    public void copySiteTplAndRes(SiteDO from, SiteDO to) throws IOException {
        getFileClient();
        if (FileStorageEnum.LOCAL.getStorage().equals(tplStorerage)) {
            File tplFrom = new File(basePath + from.getTplPath());
            File tplTo = new File(basePath + to.getTplPath());
            if (tplFrom.exists() && !tplFrom.getPath().equals(tplTo.getPath())) {
                FileUtils.copyDirectory(tplFrom, tplTo);
                File resFrom = new File(basePath + from.getResourcePath());
                if (resFrom.exists()) {
                    File resTo = new File(basePath + to.getResourcePath());
                    FileUtils.copyDirectory(resFrom, resTo);
                }
            }
        } else if (FileStorageEnum.FTP.getStorage().equals(tplStorerage)
                || FileStorageEnum.SFTP.getStorage().equals(tplStorerage)) {
            FtpFileClient ftpFileClient = (FtpFileClient) fileClient;
            //得到原站点模板路径
            String fromTpl = from.getTplPath();
            //得到资源路径
            String fromRes = from.getResourcePath();
            //得到目标模板路径
            String toTpl = to.getTplPath();
            //得到目标资源路径
            String toRes = to.getResourcePath();
            ftpFileClient.copyDirectiory(fromTpl, toTpl);
            ftpFileClient.copyDirectiory(fromRes, toRes);
        }
    }

    /**
     * 文件重名处理
     *
     * @param tplRoot  路径
     * @param filename 文件名
     * @param i        序号
     * @return 放回结果 文件名(i)
     */
    private String generateFileName(String tplRoot, String filename, int i) throws ServerException, IOException {
        String baseName = FilenameUtils.getBaseName(filename);
        String extension = FilenameUtils.getExtension(filename);
        String fileName = i != 0 ? baseName + "(" + (i) + ")" + StrUtil.C_DOT + extension : filename;
        if (FileStorageEnum.LOCAL.getStorage().equals(tplStorerage)) {
            tplRoot = basePath + tplRoot;
            File file = new File(tplRoot + SPT + fileName);
            //若果存在且不是文件夹
            if (file.exists() && !file.isDirectory()) {
                fileName = generateFileName(tplRoot, filename, i + 1);
            }
            return fileName;
        } else if (FileStorageEnum.FTP.getStorage().equals(tplStorerage)
                || FileStorageEnum.SFTP.getStorage().equals(tplStorerage)) {
            //这里捕获模板找不到的情况，
            IResFile ftpTpl = null;
            try {
                ftpTpl = get(tplRoot + SPT + fileName);
            } catch (Exception e) {
            }
            //存在且不是文件夹
            if (ftpTpl != null && !ftpTpl.isDirectory()) {
                fileName = generateFileName(tplRoot, filename, i + 1);
            }
            return fileName;
        }
        return filename;
    }
}
